home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue30 / delcom / PasDrop / ContextM.pas next >
Encoding:
Pascal/Delphi Source File  |  1998-01-08  |  5.2 KB  |  158 lines

  1. unit ContextM;
  2.  
  3. interface
  4.  
  5. uses
  6.     Windows, Messages, ComObj, ComServ, ShlObj, ActiveX, ShellApi, SysUtils, Registry;
  7.  
  8. const
  9.    CLSID_ContextMenuShellExtension: TGUID = '{A955FDC0-8819-11D1-AB26-D0E304C10000}';
  10.  
  11. type
  12.     TContextMenu = class (TComObject, IShellExtInit, IContextMenu)
  13.     private
  14.         hGlobal: THandle;
  15.         TabControlWindow: hWnd;
  16.         EditControl: hWnd;
  17.         procedure DropOnDelphi;
  18.     public
  19.         function QueryContextMenu (Menu: hMenu; indexMenu, idCmdFirst, idCmdLast,
  20.                                    uFlags: UInt): HResult; stdcall;
  21.         function InvokeCommand (var lpici: TCMInvokeCommandInfo): HResult; stdcall;
  22.         function GetCommandString (idCmd, uType: UInt; pwReserved: PUInt;
  23.                                    pszName: LPSTR; cchMax: UINT): HResult; stdcall;
  24.         function Initialize (pidlFolder: PItemIDList; lpdobj: IDataObject;
  25.                                   hKeyProgID: HKEY): HResult; stdcall;
  26.     end;
  27.  
  28. implementation
  29.  
  30. function TabControlEnumerator (Wnd: hWnd; cm: TContextMenu): Boolean; stdcall;
  31. var
  32.     szBuffer: array [0..255] of Char;
  33. begin
  34.     Result := True;
  35.     GetClassName (Wnd, szBuffer, sizeof (szBuffer));
  36.     if CompareText (szBuffer, 'TTabControl') = 0 then begin
  37.         Result := False;
  38.         cm.TabControlWindow := Wnd;
  39.     end;
  40. end;
  41.  
  42. function EditControlEnumerator (Wnd: hWnd; cm: TContextMenu): Boolean; stdcall;
  43. var
  44.     szBuffer: array [0..255] of Char;
  45. begin
  46.     Result := True;
  47.     GetClassName (Wnd, szBuffer, sizeof (szBuffer));
  48.     if CompareText (szBuffer, 'TEditControl') = 0 then begin
  49.         Result := False;
  50.         cm.EditControl := Wnd;
  51.     end;
  52. end;
  53.  
  54. procedure TContextMenu.DropOnDelphi;
  55. var
  56.     EditWindow: hWnd;
  57. begin
  58.     EditWindow := FindWindow ('TEditWindow', Nil);
  59.     if EditWindow <> 0 then begin
  60.         TabControlWindow := 0;
  61.         EnumChildWindows (EditWindow, @TabControlEnumerator, Integer (Self));
  62.         if TabControlWindow <> 0 then begin
  63.             EditControl := 0;
  64.             EnumChildWindows (EditWindow, @EditControlEnumerator, Integer (Self));
  65.             if (EditControl <> 0) and (hGlobal <> 0) then begin
  66.                 SendMessage (EditControl, wm_DropFiles, hGlobal, 0);
  67.             end;
  68.         end;
  69.     end;
  70. end;
  71.  
  72. // The Shell calls this method when it's time for the context menu handler to
  73. // add its own custom menu entries to the menu itself.  We return the number
  74. // of entries that we've added.
  75.  
  76. function TContextMenu.QueryContextMenu (Menu: hMenu; indexMenu, idCmdFirst,
  77.                                         idCmdLast, uFlags: uInt): HResult;
  78. begin
  79.     InsertMenu (Menu, indexMenu, mf_String or mf_ByPosition, idCmdFirst, 'Open in Delphi');
  80.     Result := 1;
  81. end;
  82.  
  83. // The Shell calls this method when our custom menu item has been clicked by
  84. // the user.  In other words - it's time to do the business...
  85.  
  86. function TContextMenu.InvokeCommand (var lpici: TCMInvokeCommandInfo): HResult;
  87. begin
  88.     // Ensure we're not being called by an application
  89.     Result := E_Fail;
  90.     if HiWord (Integer (lpici.lpVerb)) <> 0 then Exit;
  91.  
  92.     // Verb can only be zero since we only installed one menu item
  93.     Result := E_InvalidArg;
  94.     if LoWord (lpici.lpVerb) <> 0 then Exit;
  95.  
  96.     // Execute the notepad with the specified file
  97.     Result := NoError;
  98.     DropOnDelphi;
  99. end;
  100.  
  101. // The Shell calls this method to get a 'hint' string for the custom menu item
  102.  
  103. function TContextMenu.GetCommandString (idCmd, uType: uInt; pwReserved: puInt;
  104.                                         pszName: LPSTR; cchMax: uInt): HRESULT;
  105. begin
  106.     Result := E_InvalidArg;
  107.     if idCmd = 0 then begin
  108.         strCopy (pszName, 'Open the selected source file in Delphi');
  109.         Result := NOERROR;
  110.     end;
  111. end;
  112.  
  113. function TContextMenu.Initialize (pidlFolder: PItemIDList; lpdobj: IDataObject;
  114.                                   hKeyProgID: HKEY): HResult;
  115. var
  116.     medium: TStgMedium;
  117.     fe: TFormatEtc;
  118.     pSrc, pDst: PChar;
  119. begin
  120.     with fe do begin
  121.         cfFormat := CF_HDROP;
  122.         ptd := Nil;
  123.         dwAspect := DVASPECT_CONTENT;
  124.         lindex := -1;
  125.         tymed := TYMED_HGLOBAL;
  126.     end;
  127.  
  128.     // Fail the call if lpdobj is Nil.
  129.     Result := E_Fail;
  130.     if lpdobj = Nil then Exit;
  131.  
  132.     // Render the data referenced by the IDataObject pointer to an HGLOBAL
  133.     // storage medium in CF_HDROP format.
  134.     Result := lpdobj.GetData(fe, medium);
  135.     if Failed (Result) then Exit;
  136.  
  137.     // If only one file is selected, copy global handle.
  138.     // Otherwise fail the call.
  139.     if DragQueryFile (medium.hGlobal, $FFFFFFFF, Nil, 0) = 1 then
  140.     begin
  141.         { Copy the global handle }
  142.         hGlobal := GlobalAlloc (gmem_Moveable, GlobalSize (medium.hGlobal));
  143.         pSrc := GlobalLock (medium.hGlobal);  pDst := GlobalLock (hGlobal);
  144.         Move (pSrc^, pDst^, GlobalSize (medium.hGlobal));
  145.         GlobalUnlock (medium.hGlobal);  GlobalUnlock (hGlobal);
  146.         Result := NOERROR;
  147.     end
  148.     else Result := E_Fail;
  149.  
  150.     ReleaseStgMedium (medium);
  151. end;
  152.  
  153. initialization
  154.     TComObjectFactory.Create (ComServer, TContextMenu, CLSID_ContextMenuShellExtension,
  155.                              '', 'Delphi 3.0 ContextMenu Example', ciMultiInstance);
  156.  
  157. end.
  158.